Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.x] Refactor the HasMany fieldtype #556

Merged
merged 17 commits into from
Jul 12, 2024
Merged

Conversation

duncanmcclean
Copy link
Member

@duncanmcclean duncanmcclean commented Jul 11, 2024

This pull request refactors how the Has Many fieldtype handles the saving of relationship updates, to allow for proper support of Has Many fields when using revisions.

When I was digging into #550, I realised that the HasMany fieldtype was pretty broken when used alongside Revisions. Related models were disappearing when trying to save a revision, publishing a revision would throw an error, etc.

This was happening due to how the Has Many fieldtype has worked until now. When you save a model, it'll run the values through the relevant fieldtype process methods.

In the case of the Has Many fieldtype, the process method was where it updated the model's relationships. This has worked fine until we implemented revisions, where you don't want it those relationships to be actually updated until you "publish" the revision.

To address these issues, I had to do quite a bit of refactoring around how & when relationship updates happen. Here's a few notes on the implementation, for those interested:

  • Created a new Relationships class to saving relationship updates.
    • It accepts the model and an array of relationship values.
    • It'll loop through the model's blueprint, find any relationship fields (just Has Many fields for now), then it'll go and run the "save" code specific to that type of Eloquent relationship.
    • The Relationships::save method then gets called right after the model is saved (or the revision is published).
  • Removed the HasManyFieldtype::process method in favour of the new Relationships stuff.
  • One of the issues I facaded was trying to keep hold of the related model IDs when saving revisions/newing up models from the revision data.
    • I ended up adding a runwayRelationships property to the model to handle this. It's just a simple array with IDs in it.
      • They get populated in PreparesModels (before other fields get set as "attributes" on the model). They're then included in the revision's attribute data when it gets saved.
      • Then, when you "new" up a model from a revision (in HasRunwayResource::makeFromRevision), it sets the property again, which is then accessed when publishing a revision in HasRunwayResource::publish

@duncanmcclean duncanmcclean marked this pull request as ready for review July 12, 2024 14:45
@duncanmcclean duncanmcclean merged commit 8c4aa0a into 7.x Jul 12, 2024
@duncanmcclean duncanmcclean deleted the refactor-has-many-fieldtype branch July 12, 2024 14:46
Copy link

Released as part of v7.6.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant